package com.madzone.wiki.gae.ds.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jdo.Extent;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Text;
import com.madzone.gae.filem.model.TextFile;

@PersistenceCapable
public class WikiPage
{
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;
    
    @Persistent
    private String name;
    
    @Persistent
    private String wikiName;
    
    @Persistent
    private Date lastModifiedDate;
    
    @Persistent
    private long fileSize;
    
    @Persistent
    private int version;
    
    @Persistent
    private String author;
    
    @Persistent
    private TextFile wikiText;
    
    @Persistent
    private String[] attributeNames;
    
    @Persistent
    private String[] attributeValues;
    
    public Map<String, String> getAttributes() {
    	Map<String, String> returnMap = new HashMap<String, String>();
    	if (attributeNames != null && attributeValues != null) {
    		for(int i = 0; i < attributeNames.length; i++) {
    			returnMap.put(attributeNames[i], attributeValues[i]);
    		}
    	}
		return returnMap;
	}

	public void setAttributes(Map<String, String> attributesMap) {
		if (attributesMap != null) {
			attributeNames = new String[attributesMap.size()];
			attributeValues = new String[attributesMap.size()];
			int i = 0;
			for(Map.Entry<String, String> entry : attributesMap.entrySet()) {
				String key = entry.getKey();
				String value = entry.getValue();
				attributeNames[i] = key;
				attributeValues[i] = value;
			}
		}
	}

	public WikiPage() {
    }
    
	public WikiPage(String name, String wikiName, Date lastModifiledDate, long fileSize, int version, String author,Map<String, String> attributes, String content) {
        this.name = name;
        this.wikiName = wikiName;
        this.fileSize = fileSize;
        this.version = version;
        this.lastModifiedDate = new Date();
        this.author = author;
        setAttributes(attributes);
        this.wikiText = new TextFile(name, content);
    }

    public Key getKey()
    {
        return key;
    }

    public String getName()
    {
        return name;
    }

    public void setName( String name )
    {
        this.name = name;
    }

    public String getWikiName()
    {
        return wikiName;
    }

    public void setWikiName( String wikiName )
    {
        this.wikiName = wikiName;
    }

    public Date getLastModifiedDate()
    {
        return lastModifiedDate;
    }

    public void setLastModifiedDate( Date lastModifiedDate )
    {
        this.lastModifiedDate = lastModifiedDate;
    }

    public long getFileSize()
    {
        return fileSize;
    }

    public void setFileSize( long fileSize )
    {
        this.fileSize = fileSize;
    }

    public int getVersion()
    {
        return version;
    }

    public void setVersion( int version )
    {
        this.version = version;
    }

    public String getAuthor()
    {
        return author;
    }

    public void setAuthor( String author )
    {
        this.author = author;
    }
    
    public String getWikiTextString() {
    	TextFile file = getWikiText();
    	String wikiTextStr = "";
    	if (file != null) {
    		Text content = file.getContent();
    		if (content != null) {
    			wikiTextStr = content.getValue();
    		}
    	}
    	return wikiTextStr;
	}

	public void setWikiText(String wikiTextString) {
		TextFile file = getWikiText();
		if (file == null) {
			file = new TextFile(name, wikiTextString);
		} else {
			file.setContentString(wikiTextString);
		}
	}
	
	public TextFile getWikiText() {
    	return this.wikiText;
	}
    
    public void setWikiText(TextFile wikiText) {
		this.wikiText = wikiText;
	}

	public void save() {
		PersistenceManager pm = PMF.getPM();
		try {
			pm.makePersistent(this);
		} finally {
			//pm.close();
		}
	}
	
	public void delete() {
		PersistenceManager pm = PMF.getPM();
		try {
			pm.deletePersistent(this);
		} finally {
			//pm.close();
		}
	}
	
	public static List<WikiPage> getByName(String pageName) {
		return WikiPage.getByName(pageName, false);
	}
	
	public static List<WikiPage> getAllWikiPages() {
		PersistenceManager pm = PMF.getPM();
		try {
			List<WikiPage> pages = new ArrayList<WikiPage>();
			Extent<WikiPage> extent = pm.getExtent(WikiPage.class, false);
			for (WikiPage page : extent) {
				pages.add(page);
			}
			return pages;
		} finally {
			//pm.close();
		}
	}
	
	public static int getWikiPagesCount() {
		List<WikiPage> pages = getAllWikiPages();
		return pages.size();
	}

	public static List<WikiPage> getByName(String pageName, boolean loadWikiText) {
		String query = "select from " + WikiPage.class.getName() + " where name == '" + pageName +"'";
		PersistenceManager pm = PMF.getPM();
		try {
			List<WikiPage> pages = (List<WikiPage>) pm.newQuery(query).execute();
			return pages;
		} finally {
			//pm.close();
		}
	}

	public static WikiPage getByName(String page, int version, boolean loadWikiText) {
		//String query = "select from " + WikiPage.class.getName() + " where name == :pageName and version = :version";
		PersistenceManager pm = PMF.getPM();
		Query query = null;
		List<WikiPage> pages = null;
		WikiPage returnPage = null;
		if (version != -1) {
			query = pm.newQuery(WikiPage.class, "name == pageName && version == versionInt");
			query.declareParameters("String pageName, int versionInt");
			pages = (List<WikiPage>) query.execute(page, version);
		} else {
			query = pm.newQuery(WikiPage.class, "name == pageName");
			query.declareParameters("String pageName");
			query.setOrdering("version descending");
			query.setRange(0, 1);
			pages = (List<WikiPage>) query.execute(page);
		}
		try {
			if (pages != null && pages.size() > 0) {
				returnPage = pages.get(0);
				if(loadWikiText) {
					returnPage.getWikiText();
				}
				return pages.get(0);
			} else {
				return returnPage;
			}
		} finally {
			//pm.close();
		}
	}

}
